package club.zhilin.guli.service.trade.service.impl;

import club.zhilin.guli.common.base.result.CommonResult;
import club.zhilin.guli.service.base.dto.CourseDTO;
import club.zhilin.guli.service.base.dto.MemberDTO;
import club.zhilin.guli.service.trade.domain.Order;
import club.zhilin.guli.service.trade.domain.PayLog;
import club.zhilin.guli.service.trade.feign.IEduCourseService;
import club.zhilin.guli.service.trade.feign.IUserCenterMemberService;
import club.zhilin.guli.service.trade.mapper.OrderMapper;
import club.zhilin.guli.service.trade.service.IOrderService;
import club.zhilin.guli.service.trade.service.IPayLogService;
import club.zhilin.guli.service.trade.utils.OrderUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

/**
 * <p>
 * 订单 服务实现类
 * </p>
 *
 * @author zhilin
 * @since 2022-03-01 12:56:55
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    private final IEduCourseService iEduCourseService;
    private final IUserCenterMemberService iUserCenterMemberService;
    private final IPayLogService iPayLogService;

    @Override
    public CommonResult<String> saveOrder(String courseId, String id) {
        Order order = baseMapper.selectOne(new LambdaQueryWrapper<Order>().eq(Order::getCourseId, courseId).eq(Order::getMemberId, id));
        if (order != null) {
            // 订单已存在则直接返回订单id
            return CommonResult.success("生成订单成功", order.getId());
        }
        // 查询用户信息
        CommonResult<CourseDTO> courseDTO = iEduCourseService.selectCourseDTO(courseId);
        CommonResult<MemberDTO> memberDTO = iUserCenterMemberService.selectMemberByMemberId(id);
        Order data = assembleOrder(courseDTO.getData(), memberDTO.getData());
        baseMapper.insert(data);
        return CommonResult.success("生成订单成功", data.getId());
    }

    @Override
    public Boolean selectUserIsPaid(String courseId, String id) {
        Long count = baseMapper.selectCount(new LambdaQueryWrapper<Order>().eq(Order::getCourseId, courseId).eq(Order::getMemberId, id).eq(Order::getIsDeleted, 0).eq(Order::getStatus, 1));
        return count.intValue() > 0;
    }

    @Override
    public boolean removeOrder(String orderId, String id) {
        return this.remove(new LambdaQueryWrapper<Order>().eq(Order::getId, orderId).eq(Order::getMemberId, id));
    }

    @Override
    public Order getOrderByOrderNo(String orderNo) {
        return this.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNo, orderNo));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderStatus(Map<String, String> map) {
        // 更新订单状态
        Order order = this.getOrderByOrderNo(map.get("out_trade_no"));
        order.setStatus(true);
        this.updateById(order);

        // 记录支付日志
        PayLog payLog = new PayLog();
        payLog.setOrderNo(order.getOrderNo());
        payLog.setPayTime(new Date());
        payLog.setPayType(1);
        payLog.setTotalFee(order.getTotalFee().longValue());
        payLog.setTradeState(map.get("result_code"));
        payLog.setTransactionId(map.get("transaction_id"));
        payLog.setAttr(new Gson().toJson(map));
        iPayLogService.save(payLog);
        iEduCourseService.updateCourseBuyCount(order.getCourseId());
    }

    @Override
    public boolean selectPaidStatus(String orderNo, String id) {
        Order order = this.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNo, orderNo).eq(Order::getMemberId, id));
        return order.getStatus();
    }

    /**
     * 组装order
     *
     * @param courseDTO 课程dto
     * @param memberDTO 会员dto
     * @return order
     */
    private Order assembleOrder(CourseDTO courseDTO, MemberDTO memberDTO) {
        Order order = new Order();
        order.setOrderNo(OrderUtil.generateOrderNo());
        order.setCourseId(courseDTO.getId());
        order.setCourseTitle(courseDTO.getTitle());
        order.setCourseCover(courseDTO.getCover());
        order.setTeacherName(courseDTO.getTeacherName());
        order.setTotalFee(courseDTO.getPrice().multiply(new BigDecimal(100)));
        order.setMemberId(memberDTO.getId());
        order.setMobile(memberDTO.getMobile());
        order.setNickname(memberDTO.getNickname());
        order.setStatus(false);
        order.setPayType(1);
        return order;
    }
}
